
#include "stdafx.h"
#include "PropertiesWnd.h"
#include "Resource.h"
#include "MainFrm.h"
#include "AppWinMFC.h"
#include "MFCSubClasses.h"
#include "UserDefinedPropertyDlg.h"
#include "ChildView.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CResourceViewBar
CPropertiesWnd::CPropertiesWnd()
{
 m_CurrentProperty = 0;
}

CPropertiesWnd::~CPropertiesWnd()
{
}

BEGIN_MESSAGE_MAP(CPropertiesWnd, CDockablePane)
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_WM_CONTEXTMENU()
    ON_REGISTERED_MESSAGE(AFX_WM_PROPERTY_CHANGED, OnPropertyChanged)
	ON_COMMAND(ID_EXPAND_ALL, OnExpandAllProperties)
	ON_UPDATE_COMMAND_UI(ID_EXPAND_ALL, OnUpdateExpandAllProperties)
	ON_COMMAND(ID_SORTPROPERTIES, OnSortProperties)
	ON_UPDATE_COMMAND_UI(ID_SORTPROPERTIES, OnUpdateSortProperties)
	ON_COMMAND(ID_ADDUSERDEFINED, OnAddUserDefined)
	ON_UPDATE_COMMAND_UI(ID_ADDUSERDEFINED, OnUpdateAddUserDefined)
	ON_COMMAND(ID_PROPERTIES2, OnProperties2)
	ON_UPDATE_COMMAND_UI(ID_PROPERTIES2, OnUpdateProperties2)
	ON_WM_SETFOCUS()
	ON_WM_SETTINGCHANGE()
	ON_WM_CLOSE()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CResourceViewBar message handlers

void CPropertiesWnd::AdjustLayout()
{
	if (GetSafeHwnd() == NULL)
	{
		return;
	}

	CRect rectClient;
	GetClientRect(rectClient);

	int cyTlb = m_wndToolBar.CalcFixedLayout(FALSE, TRUE).cy;

	m_wndToolBar.SetWindowPos(NULL, rectClient.left, rectClient.top, rectClient.Width(), cyTlb, SWP_NOACTIVATE | SWP_NOZORDER);
	m_wndPropList.SetWindowPos(NULL, rectClient.left, rectClient.top + cyTlb, rectClient.Width(), rectClient.Height() - cyTlb, SWP_NOACTIVATE | SWP_NOZORDER);
}

int CPropertiesWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDockablePane::OnCreate(lpCreateStruct) == -1)
		return -1;

	CRect rectDummy;
	rectDummy.SetRectEmpty();

	if (!m_wndPropList.Create(WS_VISIBLE | WS_CHILD, rectDummy, this, 2))
	{
		TRACE0("Failed to create Properties Grid \n");
		return -1;      // fail to create
	}
    
	InitPropList();

	m_wndToolBar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE, IDR_PROPERTIES_HC);
	m_wndToolBar.LoadToolBar(IDR_PROPERTIES_HC, 0, 0, TRUE /* Is locked */);
	m_wndToolBar.CleanUpLockedImages();
	m_wndToolBar.LoadBitmap(IDB_PROPERTIES_HC, 0, 0, TRUE /* Locked */);

	m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() | CBRS_TOOLTIPS | CBRS_FLYBY);
	m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() & ~(CBRS_GRIPPER | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));
	m_wndToolBar.SetOwner(this);

	// All commands will be routed via this control , not via the parent frame:
	m_wndToolBar.SetRouteCommandsViaFrame(FALSE);

	AdjustLayout();
	m_Expanded = false;
	return 0;
}

void CPropertiesWnd::OnSize(UINT nType, int cx, int cy)
{
	CDockablePane::OnSize(nType, cx, cy);
	AdjustLayout();
}

void CPropertiesWnd::OnExpandAllProperties()
{
    if(!m_Expanded)
      m_wndPropList.ExpandAll(1);
	else
	  m_wndPropList.ExpandAll(0);
	m_Expanded = !m_Expanded;
}

void CPropertiesWnd::OnUpdateExpandAllProperties(CCmdUI* pCmdUI)
{
}

void CPropertiesWnd::OnSortProperties()
{
	m_wndPropList.SetAlphabeticMode(!m_wndPropList.IsAlphabeticMode());
}

void CPropertiesWnd::OnUpdateSortProperties(CCmdUI* pCmdUI)
{
	pCmdUI->SetCheck(m_wndPropList.IsAlphabeticMode());
}

void CPropertiesWnd::OnAddUserDefined()
{
  CUserDefinedPropertyDlg dlg(theApp.GetMainWnd(),theApp.m_OgitorsRoot->GetSelected()->GetEditorType());

  if(dlg.DoModal() == IDOK)
  {
	CBaseEditor *ed = theApp.m_OgitorsRoot->GetSelected();
	ed->AddCustomProperty(dlg.m_Name.c_str(),dlg.m_TypeName.c_str());
	ed->SetSelected(false);
	ed->SetSelected(true);
  }
}

void CPropertiesWnd::OnUpdateAddUserDefined(CCmdUI* pCmdUI)
{
  pCmdUI->Enable((int)theApp.m_OgitorsRoot->GetSelected());
}

void CPropertiesWnd::OnProperties2()
{
	// TODO: Add your command handler code here
}

void CPropertiesWnd::OnUpdateProperties2(CCmdUI* pCmdUI)
{
    pCmdUI->Enable(FALSE);
}

void CPropertiesWnd::InitPropList()
{
	SetPropListFont();

	m_wndPropList.EnableHeaderCtrl(FALSE);
	m_wndPropList.EnableDescriptionArea();
	m_wndPropList.SetVSDotNetLook();
	m_wndPropList.MarkModifiedProperties();
	m_wndPropList.SetCustomColors(RGB(255,255,255),RGB(0,0,0),RGB(224,224,224),RGB(0,0,128),RGB(224,224,224),RGB(0,0,0),RGB(192,192,192));

	CMFCPropertyGridProperty::m_strFormatFloat = _T("%.2f");
}

void CPropertiesWnd::OnSetFocus(CWnd* pOldWnd)
{
	CDockablePane::OnSetFocus(pOldWnd);
	m_wndPropList.SetFocus();
}

void CPropertiesWnd::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
	CDockablePane::OnSettingChange(uFlags, lpszSection);
	SetPropListFont();
}

void CPropertiesWnd::SetPropListFont()
{
	::DeleteObject(m_fntPropList.Detach());

	LOGFONT lf;
	afxGlobalData.fontRegular.GetLogFont(&lf);

	NONCLIENTMETRICS info;
	info.cbSize = sizeof(info);

	afxGlobalData.GetNonClientMetrics(info);

	lf.lfHeight = info.lfMenuFont.lfHeight;
	lf.lfWeight = info.lfMenuFont.lfWeight;
	lf.lfItalic = info.lfMenuFont.lfItalic;

	m_fntPropList.CreateFontIndirect(&lf);

	m_wndPropList.SetFont(&m_fntPropList);
}

LRESULT CPropertiesWnd::OnPropertyChanged( WPARAM wparam, LPARAM lparam)
{
 CString sVal;

 CChildView *wndView = (((CMainFrame *)theApp.GetMainWnd())->getChildView());
 CMFCPropertyGridProperty* prop = (CMFCPropertyGridProperty*)lparam;
 CBaseEditor *e = theApp.m_OgitorsRoot->GetSelected();
 if(!prop||!e) return 0;
 int iBinding = prop->GetData();

 if(prop->IsKindOf(RUNTIME_CLASS( CMFCPropertyGridColorProperty )))
 {
   sVal.Format(_T("%d"),((CMFCPropertyGridColorProperty*)lparam)->GetColor());
 }
 else
 {
     if(((CExMFCPropertyGridProperty*)prop)->IsComplexParent())
     {
         CString tmpval;
         sVal = _T("");
         for(int cidx = 0;cidx < prop->GetSubItemsCount();cidx++)
         {
             tmpval.Format(_T("%f "), prop->GetSubItem(cidx)->GetValue().fltVal);
             sVal += tmpval;
         }
     }
     else
     {
         variant_t dummy = prop->GetValue();
         if(dummy.vt == VT_R4)
             sVal.Format(_T("%f"),dummy.fltVal);
         else if(dummy.vt == VT_BOOL)
             sVal = dummy.boolVal ? "1":"0";
         else
             sVal = dummy;
     }
 }
 e->ExecuteSetFunction(iBinding,ConvertToApoString(sVal),false);
 wndView->Invalidate();
 return 0;
}
void CPropertiesWnd::OnClose()
{
	// TODO: Add your message handler code here and/or call default
    ShowWindow(SW_HIDE);
	//CDockablePane::OnClose();
}

void CPropertiesWnd::OnContextMenu(CWnd* pWnd, CPoint point)
{
    if (pWnd != &m_wndPropList || theApp.m_OgitorsRoot->GetSelected() == 0)
	{
		CDockablePane::OnContextMenu(pWnd, point);
		return;
	}

	CPoint test = point; 
	m_wndPropList.ScreenToClient(&test);

	CMFCPropertyGridProperty *prop = m_wndPropList.HitTest(test);
    CBaseEditor *e = ClientRoot::getInstance().GetSelected();
    if(!e || !prop) return;

    int iBinding = prop->GetData();

	m_CurrentProperty = prop;
    m_wndPropList.SetFocus();

    if(iBinding >= CUSTOM_PROPERTY_BINDING || iBinding == BIND_CUSTOMPROPERTY)
	{
	    theApp.GetContextMenuManager()->ShowPopupMenu(IDR_USERDEFINEDPROPERTIES, point.x, point.y, theApp.m_pMainWnd, TRUE);
	}
	else
	{
		StringVector menuList;
		if(e->GetPropertyContextMenu(iBinding, menuList))
        {
		    int counter = 0;
            CMenu *menu = new CMenu();
            menu->CreatePopupMenu();

		    for(unsigned int i = 0;i < menuList.size();i++)
		    {
		        if(menuList[i] != "")
		        {                 
                    menu->AppendMenu(0,ID_CONTEXTMENU_START + i,CString(menuList[i].c_str()));
					counter++;
				}
		    }
			if(counter)
			{
                int retval = TrackPopupMenu(menu->GetSafeHmenu(),TPM_RETURNCMD,point.x,point.y,0,theApp.m_pMainWnd->GetSafeHwnd(),NULL);
                e->OnPropertyContextMenu(iBinding, retval - ID_CONTEXTMENU_START);
			}
        }
    }
}
